package com.xianniu.ltc.aspect;

import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.engine.ID;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rebuild.core.Application;
import com.rebuild.core.BootEnvironmentPostProcessor;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.configuration.ConfigBean;
import com.rebuild.core.configuration.general.TransformManager;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.service.approval.*;
import com.rebuild.core.service.general.transform.RecordTransfomer;
import com.rebuild.web.BaseController;
import com.xianniu.ltc.mapper.TRbshangji4Mapper;
import com.xianniu.ltc.mapper.TUserMapper;
import com.xianniu.ltc.model.entity.TUserDTO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 审核过后需要判断后续流程是否审核通过
 * @Author: dingyx
 * @Date: 2022/1/13 11:44 上午
 */
@Slf4j
@Aspect
@Component
public class ApprovalAfterAspect extends BaseController {
    @Resource
    private TUserMapper tUserMapper;
    @Resource
    private HttpServletRequest httpServletRequest;
    @Resource
    private TRbshangji4Mapper tRbshangji4Mapper;

    /**
     * 审批后或者提交后处理
     */
    @Pointcut("execution(public * com.rebuild.web.robot.approval.ApprovalController.doApprove(..)) || " +
            "execution(public * com.rebuild.web.robot.approval.ApprovalController.doSubmit(..))")
    public void userModify(){}


    @After("userModify()")
    public void after(JoinPoint joinPoint) throws Throwable {
        String method = joinPoint.getSignature().getName();
        final ID recordId = getIdParameterNotNull(httpServletRequest, "record");
        final Integer state = getIntParameter(httpServletRequest, "state");
        // 如果是审批被驳回 则不需要处理
        if("doApprove".equalsIgnoreCase(method) && ApprovalState.REJECTED.getState() == state){
            log.info("方法：{},审批被驳回 则不需要处理", method);
            return;
        }
        // 审批后：查询下一审批人账号是否可用，不可用则直接审批跳过
        approvalSkip(recordId);
        // 发票申请审批通过：自动生成已开票记录
        String sourceEntity = MetadataHelper.getEntityName(recordId);
        if (sourceEntity.equalsIgnoreCase("rbkaipiao0")){
            log.info("发票申请审批通过：自动生成已开票记录:{}", recordId.toString());
            doMakeInvoiceAfter(recordId);
            // 售前协同审批通过回填报价金额含税，报价金额未税，综合税率，售前协同ID赋值对应商机字段
        }else if (sourceEntity.equalsIgnoreCase("shouqianxietong28")){
            log.info("售前协同审批通过回填报价金额含税，报价金额未税，综合税率，售前协同ID赋值对应商机字段:{}", recordId.toString());
            doPreSalesSynergyAfter(recordId);
        }
    }

    /**
     * 功能描述: 审批后：查询下一审批人账号是否可用，不可用则直接审批跳过
     *
     * @Param: [method]
     * @Return: void
     * @Author: wrj
     * @Date: 2022/3/7 4:38 下午
     */
    private void approvalSkip(ID recordId){
        try{
            log.info("审批后：查询下一审批人账号是否可用，不可用则直接审批跳过------>开始：{}", recordId.toString());
            final ApprovalStatus status = ApprovalHelper.getApprovalStatus(recordId);
            ApprovalProcessor approvalProcessor = new ApprovalProcessor(recordId, status.getApprovalId());
            List<TUserDTO> approvalUsers;
            // 如果当前节点没有审批完成并且审批不能缺少A且这个审批人A已离职
            while (CollectionUtil.isNotEmpty(approvalUsers = needAutoApproval(approvalProcessor, status, recordId))) {
                for(TUserDTO user : approvalUsers){
                    ID approverId = ID.valueOf(user.getUserId());
                    // 审批通过
                    approvalProcessor.approve(approverId, ApprovalState.APPROVED, "账号不可用，自动跳过", null);
                    log.info("记录{}已经由{}已经自动审批通过", recordId, approverId);
                }
            }
            log.info("审批后：查询下一审批人账号是否可用，不可用则直接审批跳过------>结束：{}", recordId.toString());
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 功能描述: 开票审批审批通过后，自动调用转换【已开票】配置，生成一条已开票记录
     *
     * @Param: [sourceRecord]
     * @Return: void
     * @Author: wrj
     * @Date: 2022/3/7 5:06 下午
     */
    private void doMakeInvoiceAfter(ID sourceRecord){
        log.info("开票审批审批通过后，自动调用转换【已开票】配置，生成一条已开票记录------>结束：{}", sourceRecord.toString());
        String tenantCode = UserContextHolder.getTenant();
        Object[] o = Application.getQueryFactory().uniqueNoFilter(sourceRecord, EntityHelper.ApprovalState);
        // 审批通过
        if (o != null && o[0].equals(10)){
            //开票申请转换已开票转换记录ID
            ID transid = ID.valueOf("037-017be384e73a058b");
            ConfigBean config = TransformManager.instance.getTransformConfig(transid, null, BootEnvironmentPostProcessor.getDefaultTenant());
            Entity targetEntity = MetadataHelper.getEntity(config.getString("target"));

            RecordTransfomer transfomer = new RecordTransfomer(targetEntity, (JSONObject) config.getJSON("config"));
            if (!transfomer.checkFilter(sourceRecord, tenantCode)) {
                log.info("没有权限进行转换，数据：{}",sourceRecord.toString());
            }

            ID newId = transfomer.transform(sourceRecord, tenantCode);
            log.info("开票申请转换已开票转换记录成功：{}", newId.toString());
        }
        log.info("开票审批数据状态不是审批通过，不自动生成已开票记录：{}", sourceRecord.toString());
    }

    private void doPreSalesSynergyAfter(ID sourceRecord){
        log.info("售前协同审批通过回填报价金额含税，报价金额未税，综合税率，售前协同ID赋值对应商机字段------>开始：{}", sourceRecord.toString());
        Object[] o = Application.getQueryFactory().uniqueNoFilter(sourceRecord, "guanlianshangji","baojiajinehanshui","baojiajineweishui","zongheshuilv","xietongleixing");
        if (o != null){
            // 协同类型=商机报价
            if (o[4].toString().equalsIgnoreCase("019-017c2625e5b000f7")){
                String guanlianshangji = o[0].toString();
                BigDecimal baojiajinehanshui = new BigDecimal(o[1].toString());
                BigDecimal baojiajineweishui = new BigDecimal(o[2].toString());
                BigDecimal zongheshuilv = new BigDecimal(o[3].toString());
                tRbshangji4Mapper.updateSjByPreSalesSynergyInfo(guanlianshangji, sourceRecord.toString(), baojiajinehanshui, baojiajineweishui, zongheshuilv);
                log.info("售前协同审批通过回填报价金额含税，报价金额未税，综合税率，售前协同ID赋值对应商机字段------>结束：{}", sourceRecord.toString());
            }
        }
    }

    private List<TUserDTO> needAutoApproval(ApprovalProcessor approvalProcessor, ApprovalStatus status, ID recordId){
        String tenantCode = UserContextHolder.getTenant();
        ApprovalState currentState = status.getCurrentState();
        // 如果当前状态不是审核中 不需要处理
        if(!currentState.equals(ApprovalState.PROCESSING)){
            log.info("如果当前状态不是审核中 不需要处理:{}", recordId.toString());
            return new ArrayList<>();
        }
        FlowNode currentNode = approvalProcessor.getCurrentNode(tenantCode);
        FlowNode rootNode = approvalProcessor.getRootNode(tenantCode);
        // 处理用户，反序列化SELF/DEPART
        Set<ID> idSet = currentNode.getSpecUsers(null, recordId, rootNode);
        List<String> idList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(idSet)){
            idList = idSet.stream().map(ID::toString).collect(Collectors.toList());
        }
        QueryWrapper<TUserDTO> wrapper = new QueryWrapper<>();
        wrapper.in("user_id", idList);
        wrapper.eq("tenant_code", tenantCode);
        wrapper.eq("IS_DISABLED", "T");
        List<TUserDTO> userList = tUserMapper.selectList(wrapper);
        log.info("需要自动跳过审批的人员名单{}", JSONArray.toJSONString(userList));
        if (userList.size()>0){
            // 获取下一个节点步骤
            FlowNode nextNode = approvalProcessor.getCurrentNode(UserContextHolder.getTenant());
            // 或签 且 或签人数大于1的情况下不自动审批通过，跳过即可
            if (nextNode.getSignMode().equalsIgnoreCase(FlowNode.SIGN_OR)
                    && idList.size() > userList.size()){
                userList = new ArrayList<>();
            }
        }
        return userList;
    }
}
